// This kernel perform vectorized floating-point addition/multiplication
// to demonstrate how parallel processing can accelerate computation
// 2020.06.17 by wangdong@bjtu.edu.cn
//#include "ap_int.h"
// #include <stdio.h> 


#include "custypedef.h"


//--------------------- Baseline -----------------------//
#define BUFFER_DEPTH 128
extern "C" {
void featureRead(
            	DATA_TYPE *A_in,
				uint data_num,
				REFERENCE_STREAM(k2k<vec_type>, 16, img_channels)
				)
{
	#pragma HLS INTERFACE m_axi port = A_in  offset = slave bundle = gmem0 num_read_outstanding=1 max_read_burst_length=1
	#pragma HLS INTERFACE axis  port = img_channels depth=16

	DATA_TYPE img_ori_0[BUFFER_DEPTH];
	DATA_TYPE img_ori_1[BUFFER_DEPTH];
	DATA_TYPE img_ori_2[BUFFER_DEPTH];
	
	volatile int Rdcnt = 0;
	for(uint k = 0; k<DATA_SIZE_M; k++){
		for (int i = 0; i < DATA_SIZE_W; i++)
		{
			img_ori_1[i] = A_in[i + k * DATA_SIZE_W * DATA_SIZE_H];
		}
		for (int i = 0; i < DATA_SIZE_W; i++)
		{
			img_ori_2[i] = A_in[i + DATA_SIZE_W + k * DATA_SIZE_W * DATA_SIZE_H];
		}
		
		for(int i = 0; i < DATA_SIZE_H - DATA_SIZE_K + 1; i++)
		{
			for (int i = 0; i < DATA_SIZE_W; i++)
			{
				img_ori_0[i] = img_ori_1[i];
			}
			for (int i = 0; i < DATA_SIZE_W; i++)
			{
				img_ori_1[i] = img_ori_2[i];
			}
			for(uint j = 0; j< DATA_SIZE_W; j++){
				img_ori_2[j] = A_in[j + (i + 2) * DATA_SIZE_W + k * DATA_SIZE_W * DATA_SIZE_H];
			}
			
			for(uint s = 0; s<DATA_SIZE_W - DATA_SIZE_K + 1; s++){
				for(uint s2 = 0; s2 < DATA_SIZE_K; s2++){
					k2k<vec_type> _trans_img_oris;
					_trans_img_oris.data(GET_BIT(DATA_TYPE)-1, 0) = img_ori_0[s + s2];
					_trans_img_oris.data(GET_BIT(DATA_TYPE)*2-1, GET_BIT(DATA_TYPE)) = img_ori_1[s + s2];
					_trans_img_oris.data(GET_BIT(DATA_TYPE)*3-1, GET_BIT(DATA_TYPE)*2) = img_ori_2[s + s2];

					img_channels.write(_trans_img_oris);
					++Rdcnt;
				}
			}
		}
	}
}

}
